package models

import java.util.Base64

import exceptions.BusinessError
import org.joda.time.DateTime
import play.api.libs.Codecs
import play.api.libs.json.Json

case class SToken(guid: String, profile: SProfile, expireTime: Option[DateTime]) {

  import JsonFormatters.sProfileFormatter

  val concatChar = "QWERTYUIOP~!@#$"
  lazy val token: String = {
    val jsonProfile = Json.toJson(profile).toString()
    val sExpireTime = expireTime.map(_.getMillis.toString).getOrElse("")
    val signature = Codecs.sha1(guid + concatChar + jsonProfile + concatChar + sExpireTime)
    Base64.getEncoder().encodeToString((guid + "." + jsonProfile + "." + sExpireTime).getBytes()) + "." + signature
  }

}

object SToken {

  import models.JsonFormatters.sProfileFormatter
  def validate(token: String): Boolean = {
    val sToken = parse(token)
    sToken.expireTime.map(d => d.compareTo(DateTime.now()) >= 0).getOrElse(true) &&
      sToken.token == token
  }

  def parse(token: String): SToken = {
    val tokenCodeParts = token.split("\\.")
    tokenCodeParts.toSeq match {
      case dataPart :: signature =>
        val data = String.valueOf(Base64.getDecoder.decode(dataPart)).split("\\.")
        data.toSeq match {
          case guid :: jsonProfile :: expireTime :: Nil =>
            val sProfile = Json.parse(jsonProfile).validate[SProfile].get
            SToken(guid, sProfile, Option(expireTime).map(e => new DateTime(e.toLong)))
          case _ => throw new BusinessError("令牌不正确")
        }
      case _ => throw new BusinessError("令牌不正确")
    }
  }
}

case class SProfileRoles(roleId: Int, moduleIds: Seq[Int], featureIds: Seq[Int])

case class SProfile(userId: Int, roles: Seq[SProfileRoles])

